#pragma once
#include "Globals.h"
#include "Button.h"
#include "MenuPanel.h"
#include "Pathogen.h"
#include "Input.h"
//#include "Drawable.hpp"	(Abstracted through Button.hpp)

class Graphics
{
private:
	Graphics():isWindowed(true){};

	bool isWindowed;

	/*DEVICES											DEVICES*/
	ID3DXSprite*			Sprite;						//Sprite Object	
	IDirect3D9*				Object;						//Present Device Object
	IDirect3DDevice9*		Device;						//Input Device: Mastermind		
	ID3DXFont*				FontDevice;					//Reference: Times New Roman Bold Font

	/*GRAPHICS											GRAPHICS*/
	D3DPRESENT_PARAMETERS	D3D_PP;						//Presentation Parameters
	LPDIRECT3DTEXTURE9		m_dTexture  [TEX_SIZE];		//Index: Textures
	D3DXIMAGE_INFO			m_dImageInfo[TEX_SIZE];		//Index: ImageInfo
	D3DXVECTOR3				m_dTexCenter[TEX_SIZE];		//Index: Texture Center Coordinates


public:
	inline static Graphics* Into()      
	{static Graphics engine;return &engine;}

	//=====INITIALIZATION
	void Initialize(HWND hWnd)//,HINSTANCE)
	{
		RECT		rClientRect;
		D3DCAPS9	D3DCaps;

		Object = Direct3DCreate9(D3D_SDK_VERSION);

		DWORD dwBehaviorFlags = 0;

		if(!::GetClientRect(hWnd, &rClientRect)){throw "GetClientRect() failed";}

		Object->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &D3DCaps);

		(D3DCaps.VertexProcessingCaps != 0?										//Is vertex processing supported?
			dwBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING:				//T: Use it
		dwBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING);				//F: Don't

		D3D_PP.hDeviceWindow			=	hWnd;								//What to draw to
		D3D_PP.Windowed					=	isWindowed;							//True if windowed
		D3D_PP.AutoDepthStencilFormat	=	D3DFMT_D24S8;
		D3D_PP.EnableAutoDepthStencil	=	TRUE;						
		D3D_PP.BackBufferCount			=	1;									//How many back buffers
		D3D_PP.BackBufferFormat			=	D3DFMT_X8R8G8B8;					//32 Bit Color
		D3D_PP.BackBufferHeight			=	ScreenH;							//Buffer height
		D3D_PP.BackBufferWidth			=	ScreenW;							//Buffer width
		D3D_PP.SwapEffect				=	D3DSWAPEFFECT_DISCARD;		
		D3D_PP.Flags					=	D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
		D3D_PP.PresentationInterval		=	D3DPRESENT_INTERVAL_DEFAULT;		//60fps
		D3D_PP.MultiSampleQuality		=	0;
		D3D_PP.MultiSampleType			=	D3DMULTISAMPLE_NONE;
		D3D_PP.FullScreen_RefreshRateInHz=   isWindowed?0:D3DPRESENT_RATE_DEFAULT;

		Object->CreateDevice( D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,		//Create Device
			hWnd, dwBehaviorFlags, &D3D_PP, &Device);

		//Create the sprite device
		D3DXCreateSprite(Device, &Sprite);								//Create Sprite object
		D3DXCreateFont(Device, 18, 0, 0, 0, false,				
			DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,
			DEFAULT_PITCH | FF_DONTCARE, TEXT("Times New Roman"),
			&FontDevice);	

		InitTextures();

	};
	void InitTextures()
	{
		InitTexture( TEX_KAJHTAI	,"Graphics/Countries/KajhTai.png"		);
		InitTexture( TEX_KHATOUM	,"Graphics/Countries/Khatoum.png"		);
		InitTexture( TEX_AEMPIS		,"Graphics/Countries/Aempis.png"		);
		InitTexture( TEX_FAURRIEAST	,"Graphics/Countries/Faur'riEast.png"	);
		InitTexture( TEX_FAURRIWEST	,"Graphics/Countries/Faur'riWest.png"	);
		InitTexture( TEX_VALDUTAN	,"Graphics/Countries/Valdutan.png"		);
		InitTexture( TEX_VERINWEST	,"Graphics/Countries/VerinWest.png"		);
		InitTexture( TEX_VERINEAST	,"Graphics/Countries/VerinEast.png"		);
		InitTexture( TEX_VERINCENTER,"Graphics/Countries/VerinCapitol.png"	);
		InitTexture( TEX_NEGEWEST	,"Graphics/Countries/NegeWest.png"		);
		InitTexture( TEX_NEGEEAST	,"Graphics/Countries/NegeEast.png"		);
		InitTexture( TEX_MARIANIYAH	,"Graphics/Countries/Marianiyah.png"	);
		InitTexture( TEX_SIASYA		,"Graphics/Countries/Siasya.png"		);
		InitTexture( TEX_SANKT		,"Graphics/Countries/Sankt.png"			);
		InitTexture( TEX_VALUSERRH	,"Graphics/Countries/Valuser'rh.png"	);
		InitTexture( TEX_BUTTON		,"Graphics/UI/Button.png"				);
		InitTexture( TEX_MENUPANEL	,"Graphics/UI/MenuPanel.png"			);
		InitTexture( TEX_MAP		,"Graphics/UI/Map.png"					);
		InitTexture( TEX_BAR		,"Graphics/UI/MenuDock.png"				);
	}
	void InitTexture(int Element,string Address)
	{
		D3DXCreateTextureFromFileEx										
			(Device, Address.c_str(), 0, 0, 0, 0,
			D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT,
			D3DX_DEFAULT, D3DCOLOR_XRGB(255, 255,255),
			&m_dImageInfo[Element], 0, &m_dTexture[Element]);

		D3DSURFACE_DESC Dimensions;
		m_dTexture[Element]->GetLevelDesc(0,&Dimensions);
		float X = Dimensions.Width  * 0.5f;
		float Y = Dimensions.Height * 0.5f;
		m_dTexCenter[Element] = D3DXVECTOR3(X,Y,0.0f);
	}
	
	//=====ACCESS
	ID3DXFont* GetFDevice()	{return FontDevice;};
	//=====RENDER
	void Render(L_Zone ZList, L_Object OList, L_Button BList, L_Menu MList,PrintBox Box)
	{
		HRESULT hresult;

		Device->Clear	//Clear from out last usage
			(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 
			D3DCOLOR_XRGB(0, 0, 0), 1.0f,0);	
		hresult = Device->BeginScene();		

		//===SPRITES
		Sprite->Begin(D3DXSPRITE_ALPHABLEND);	

		for each(Drawable*	toDraw in OList)
			RenderSprite(toDraw);
		for each(Zone* toDraw in ZList)
			RenderSprite(toDraw);
		for each(MenuPanel* toDraw in MList)
			if(toDraw->ShowReq() == c_eiGameState || toDraw->ShowReq() == GS_ALWAYS)
				RenderSprite(toDraw);
		for each(Button* toDraw in BList)
			if(toDraw->isActive())
				RenderSprite(toDraw);

		Sprite->End();	
		Box.Draw();
		//===PRINTBOX
		RenderButtonFont(BList);
		RenderMenuFont(MList,ZList);

		//===PRESENT
		hresult = Device->EndScene();
		Device->Present(NULL, NULL, NULL, NULL);
	}
	void RenderSprite(Drawable* toDraw)
	{	
		/**
		*	This funtion takes in a drawable object, then uses its TextureIndex
		*	(Which is given on instantiation of the object) to access an 3 arrays.
		*	The 3 arrays, given value in InitializeTextures() hold the texture, imageinfo
		*	and texture center of the sprite. That information is then passes to Sprite->Draw();
		*/
		int TextureInd = toDraw->GetTexID();				//Grab the texture index of this object
		Sprite->SetTransform(&toDraw->GetWorldTrans());		//Move the sprite into place
		Sprite->Draw(m_dTexture[TextureInd],NULL,			//Draw the sprite onto screen
			&m_dTexCenter[TextureInd],0,toDraw->GetColor());//Draw the sprite onto screen

	}
	void RenderButtonFont(L_Button List)
	{
		/**
		*	Reach into the buttons, grab their text and draw RECT
		*	and draw that onto the screen as it should be
		*/
		for each(Button* B in List){
			if(B->ShowReq() == c_eiGameState || B->ShowReq() == GS_ALWAYS){	//If this should be showing
				FontDevice->DrawTextA(NULL,B->m_sButtonText.c_str(),		//Draw the font
					B->m_sButtonText.size(),&B->Location,					//Draw the font
					DT_LEFT | DT_NOCLIP,D3DCOLOR_ARGB(255, 255, 255, 255)); //Draw the font
			}
		}
	}
	void RenderMenuFont(L_Menu M, L_Zone ZList)
	{
		for(int i(0); i < M.size(); i++)
		{
			if(M[i]->MenuTypeID() > -1 && M[i]->ShowReq() == c_eiGameState)
			{
				M[i]->UpdateTextFor(ZList[i]);
				FontDevice->DrawTextA(NULL,M[i]->sGetContent().c_str(),			//Draw the font
					M[i]->sGetContent().size(),&M[i]->RectGetRect(),			//Draw the font
					DT_LEFT | DT_NOCLIP,D3DCOLOR_ARGB(255, 255, 255, 255));		//Draw the font
			}
			else if(M[i]->MenuTypeID() == -2)
			{
				FontDevice->DrawTextA(NULL,M[i]->sGetContent().c_str(),			//Draw the font
					M[i]->sGetContent().size(),&M[i]->RectGetRect(),			//Draw the font
					DT_LEFT | DT_NOCLIP,D3DCOLOR_ARGB(255, 255, 255, 255));		//Draw the font
			}
		}
	}

	LPDIRECT3DTEXTURE9 GetTexture(int x)	{return m_dTexture  [x];};
};


